package com.aspirecn.core.datacache;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.xBaseJ.DBF;
import org.xBaseJ.xBaseJException;

import com.aspirecn.core.commons.Configuration;
import com.aspirecn.core.commons.FileUtils;
import com.aspirecn.core.object.StockBean;

/**
 * 股票行情缓存
 * 
 * @author wangxinning
 * 
 */
public class StockCache extends BaseLocalCache {

	public final static Logger logger = Logger.getLogger(StockCache.class);
	private static StockCache instance = new StockCache();
	
	private Map<String, StockBean> stockMap = new HashMap<String, StockBean>();

	private File shanghaiFile = new File(Configuration.getInstance()
			.getDownloadFilePath() + File.separator + "show2003.dbf");
	private File shenzhenFile = new File(Configuration.getInstance()
			.getDownloadFilePath() + File.separator + "sjshq.dbf");

	private StockCache() {
		load();
	}

	public static StockCache getInstance() {
		return instance;
	}

	public void load() {

		if (!loading.getAndSet(true) && Configuration.getInstance().switchStockCache()) {

			long start = System.currentTimeMillis();
			long startMem = Runtime.getRuntime().freeMemory();

			try {
				if (shanghaiFile.exists()) {
					List<StockBean> stockList = toStockList(shanghaiFile);
					if( stockList != null && !stockList.isEmpty() )
					{
						for( StockBean stockBean:stockList )
						{
							stockMap.put("sh" + stockBean.getCode(), stockBean);
						}
					}
				}

				if (shenzhenFile.exists()) {
					List<StockBean> stockList = toStockList(shenzhenFile);
					if( stockList != null && !stockList.isEmpty() )
					{
						for( StockBean stockBean:stockList )
						{
							stockMap.put("sz" + stockBean.getCode(), stockBean);
						}
					}
				}

			} catch (Exception e) {

				loading.set(false);
				logger.error("load 失败", e);
				return;
			}

			loading.set(false);
			long end = System.currentTimeMillis();
			long endMem = Runtime.getRuntime().freeMemory();
			updateFileDownloadTime();
			logger.info("股票行情信息加载完成，time=" + (end - start) + "ms,占用内存="
					+ (endMem - startMem) / FileUtils.ONE_KB + "kb");

		} else {
			logger.info("配置关闭，股票行情信息未加载");
		}
	}

	@Override
	public void clear() {

	}

	@Override
	public void reload() {

		if (this.fileIsChange()) {
			this.load();
		} else {
			logger.info("没变化，省份和城市信息未加载");
		}
	}

	public static void main(String[] args) {
		StockCache geoCache = StockCache.getInstance();
		System.out.println(geoCache.getShanghaiStockBeanList().size());
		System.out.println(geoCache.getShenzhenStockBeanList().size());
	}

	public void updateFileDownloadTime() {
		long fileDownloadTime1 = this.shanghaiFile.lastModified();
		long fileDownloadTime2 = this.shenzhenFile.lastModified();

		this.fileDownloadTime = fileDownloadTime1 + fileDownloadTime2;
	}

	// 跟上次加载时间是否变化
	protected boolean fileIsChange() {
		long fileDownloadTime1 = this.shanghaiFile.lastModified();
		long fileDownloadTime2 = this.shenzhenFile.lastModified();
		if (this.fileDownloadTime != fileDownloadTime1 + fileDownloadTime2) {
			return true;
		} else {
			return false;
		}
	}

	public StockBean getStockBean(String code)// sh+code
	{
		return this.stockMap.get(code);
	}

	public List<StockBean> getShanghaiStockBeanList() {
		return getStockBeanList("sh");
	}

	public List<StockBean> getShenzhenStockBeanList() {
		return getStockBeanList("sz");
	}

	private List<StockBean> getStockBeanList(String prefix) {
		List<StockBean> stockBeanList = new ArrayList<StockBean>();
		Iterator<Entry<String, StockBean>> ite = stockMap.entrySet().iterator();

		while (ite.hasNext()) {
			Entry<String, StockBean> tempEntry = ite.next();
			StockBean stock = tempEntry.getValue();

			if (StringUtils.startsWith(tempEntry.getKey(), prefix)) {
				stockBeanList.add(stock);
			}
		}

		return stockBeanList;
	}

	private static List<StockBean> toStockList(File file) throws xBaseJException,
			IOException {
		String fileName = file.toString();
		List<StockBean> retList = new ArrayList<StockBean>();
		DBF dbf = new DBF(fileName, "gbk");

		if (StringUtils.containsIgnoreCase(fileName, "show2003")) {

			for (int i = 0; i < dbf.getRecordCount(); i++) {
				dbf.read();

				String code = dbf.getField("S1").get();
				String name = dbf.getField("S2").get();
				StockBean stock = new StockBean();
				stock.setCode(code);
				stock.setName(StringUtils.deleteWhitespace(name));

				retList.add(stock);
			}
			
			dbf.close();
		} else if (StringUtils.containsIgnoreCase(fileName, "sjshq")) {

			for (int i = 0; i < dbf.getRecordCount(); i++) {
				dbf.read();

				String code = dbf.getField(1).get();
				String name = dbf.getField(2).get();

				StockBean stock = new StockBean();
				stock.setCode(code);
				stock.setName(StringUtils.deleteWhitespace(name));

				retList.add(stock);
			}
			
			dbf.close();
		}

		return retList;
	}
}